package com.tucanstubs.android_wheresmystuff.items;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Service provider class for filtering items on the myItems screen
 * @author team 37
 * @version 1.0 4/4/2013
 *
 */
public class Filter {
	
	//static constants for determining which type of filtering to perform
	public static final int ALL = 0;
	public static final int DATE_SORT_UP = 1;
	public static final int DATE_SORT_DOWN = 2;
	public static final int STATUS_SORT_CLAIMED = 3;
	public static final int STATUS_SORT_UNCLAIMED = 4;
	public static final int CATEGORY_SORT_LOST = 5;
	public static final int CATEGORY_SORT_FOUND = 6;
	public static final int CATEGORY_SORT_DONATION = 7;
	public static final int CATEGORY_SORT_REQUEST = 8;
	
	/**
	 * Takes in a list of items and filters the list based on the inputed filter parameter.
	 * The method then returns a list of the filtered items. See public constants for filter types.
	 * @param itemList list of items to filter
	 * @param filterParameter method by which items should be filtered
	 * @return postFiltered, the filtered list
	 */
	public static List<Item> filter(List<Item> itemList, int filterParameter) {
		List<Item> preFiltered = itemList;
		List<Item> postFiltered = new ArrayList<Item>();
		
		//determine correct method of filtering and perform the filtering
		switch (filterParameter) {
		case DATE_SORT_UP:
			
			postFiltered = dateUp(preFiltered);
			break;
		case DATE_SORT_DOWN:
			
			postFiltered = dateDown(preFiltered);
			break;
		case STATUS_SORT_CLAIMED:
			
			postFiltered = statusClaimed(preFiltered);
			break;
		case STATUS_SORT_UNCLAIMED:
			
			postFiltered = statusUnclaimed(preFiltered);
			break;
		case CATEGORY_SORT_LOST:
			
			postFiltered = categoryLost(preFiltered);
			break;
		case CATEGORY_SORT_FOUND:
			
			postFiltered = categoryFound(preFiltered);
			break;
		case CATEGORY_SORT_DONATION:
			
			postFiltered = categoryDonation(preFiltered);
			break;
		case CATEGORY_SORT_REQUEST:
			
			postFiltered = categoryRequest(preFiltered);
			break;
		default:
			
			postFiltered = preFiltered;
		}
		return postFiltered;
	}
	
	/**
	 * Filters the items by date so that the items with the most current date appear first
	 * 
	 * @param preFiltered list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> dateUp(List<Item> preFiltered) {
		List<Item> list = preFiltered;
		Collections.sort(list, new Comparator<Item>(){

			@Override
			public int compare(Item item1, Item item2) {
				
				return -(item1.getDateEntered().compareTo(item2.getDateEntered()));
			}
				
		});
		return list;
	}
	
	/**
	 * Filters the items by date so that the least current date appears first
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> dateDown(List<Item> preFiltered) {
		List<Item> list = preFiltered;
		Collections.sort(list, new Comparator<Item>(){

			@Override
			public int compare(Item item1, Item item2) {
				
				return item1.getDateEntered().compareTo(item2.getDateEntered());
			}
				
		});
		return list;
	}
	/**
	 * Filters the items so that only those that are claimed show up
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> statusClaimed(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (item.isMatchedUp()) {
				
				list.add(item);
			}
		}
		return list;
	}
	
	/**
	 * Filters the items so that only those that are unclaimed are displayed
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> statusUnclaimed(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (!item.isMatchedUp()) {
				
				list.add(item);
			}
		}
		return list;
	}
	
	/**
	 * Filters the items so that only lost items are displayed
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> categoryLost(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (item instanceof LostItem) {
				
				list.add(item);
			}
		}
		return list;
	}
	
	/**
	 * Filters the items so that found items are displayed
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> categoryFound(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (item instanceof FoundItem) {
				
				list.add(item);
			}
		}
		return list;
	}
	
	/**
	 * Filters the items so that only items of type donation are displayed
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> categoryDonation(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (item instanceof Donation) {
				
				list.add(item);
			}
		}
		return list;
		
	}
	
	/**
	 * Filters the items so that only items of type Request are displayed
	 * @param preFiltered the list of items to filter
	 * @return the list of filtered items
	 */
	private static List<Item> categoryRequest(List<Item> preFiltered) {
		List<Item> list = new ArrayList<Item>();
		
		for (Item item: preFiltered) {
			
			if (item instanceof Request) {
				
				list.add(item);
			}
		}
		return list;
	}
}
